Skip to main content

시스템 콜

시스템 콜이란?

시스템 콜(system call)은 운영체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스 이다. 보통 C나 C++과 같은 고급 언어로 작성된 프로그램들은 직접 시스템 호출을 사용할 수 없기 때문에 고급 API를 통해 시스템 호출에 접근하게 하는 방법이다.

즉, 응용프로그램에서 운영체제에게 어떠한 기능을 수행해달라고 하는 하나의 수단 이다.

시스템 콜에 대한 이해

  1. 사용자 프로세스가 시스템 콜을 요청하면 커널로 제어가 넘어옴 (사용자모드 -> 커널모드)
  2. 커널은 내부적으로 각각의 시스템 콜을 구분하기 위해 기능별로 고유번호를 할당하고 그 번호에 해당하는 제어루틴을 커널 내부에 정의
  3. 커널은 요청받은 시스템 콜에 대응하는 기능번호를 확인
  4. 커널은 그 번호에 맞는 서비스 루틴을 호출
  5. 서비스 루틴을 모두 처리하고 나면 커널 모드에서 사용자 모드로 다시 전환

시스템 콜의 유형

프로세스 제어(Process Control)

  • 끝내기(end), 중지(abort)
  • 적재(load), 실행(execute)
  • 프로세스 생성(create process)
  • 프로세스 속성 획득과 설정(get process attribute and set process attribute)
  • 시간 대기(wait time)
  • 사건 대기(wait event)
  • 사건을 알림(signal event)
  • 메모리 할당 및 해제 : malloc, free

파일 조작(File Manipulation)

  • 파일 생성(create file), 파일 삭제(delete file)
  • 열기(open), 닫기(close)
  • 읽기(read), 쓰기(write), 위치 변경(reposition)
  • 파일 속성 획득 및 설정(get file attribute and set file attribute)

장치 관리(Devide Management)

  • 장치를 요구(request devices), 장치를 방출(release device)
  • 읽기, 쓰기, 위치 변경
  • 장치 속성 획득, 장치 속성 설정
  • 장치의 논리적 부착(attach) 또는 분리(detach)

정보 유지(Information Maintenance)

  • 시간과 날짜의 설정과 획득(time)
  • 시스템 데이터의 설정과 획득(date)
  • 프로세스 파일, 장치 속성의 획득 및 설정

통신(Communication)

  • 통신 연결의 생성, 제거
  • 메시지의 송신, 수신
  • 상태 정보 전달
  • 원격 장치의 부착 및 분리

보안(protection)

  • Permission 획득
  • Permission 설정

시스템 콜 처리과정 - fork

fork

위 그림은 가장 대표적인 시스템 콜 예시인 fork() 함수의 시스템 콜 처리과정입니다.

  1. user process에서 fork() 시스템 콜을 호출

  2. C라이브러리(libc.a)에서 fork의 시스템 콜 고유번호인 '2'를 레지스터에 저장하고 0x80 인터럽트를 발생시킴

    (int 0x80에서 int는 interrupt를 뜻하는 명령어. 인터럽트가 발생했으므로 User Mode-> Kerner Mode로 전환)

  3. 이후 커널은 IDT(Interrupt Descriptor Table)에서 0x80주소에 있는 system_call()을 호출

  4. system_call()함수에서는 호출된 시스템 콜 번호와 레지스터들을 스택에 저장하고 검증

  5. 과정 4에서 스택에 옮겨놓은 값을 기반으로 sys_call_table에서 sys_fork()함수 탐색 및 호출

  6. 함수 종료 후에는 사용자 프로세스로 리턴 및 Kerner Mode -> User Mode로 전환

시스템 콜 처리과정 - open

syscall1

위 그림은 open() 시스템 콜을 사용한 예시이다.

자세한 과정은 위의 fork()와 유사하다. 대략적인 과정은 위 그림을 참고하면 도움이 될 것 같다.

시스템 콜의 매개변수 전달

필요한 기능이나 시스템의 환경에 따라 시스템 콜이 발생할 때 좀 더 많은 정보가 필요할 수 있다.

이러한 정보가 담긴 매개변수를 운영체제에 전달하기 위한 3가지의 방법이 존재한다.

  1. 레지스터 이용 : 가장 간단한 방법으로, 매개변수를 레지스터에 넣어 전달한다. 단, 레지스터 개수보다 매개변수의 개수가 더 많을 수도 있다.
  2. 메모리 블록 이용 : 매개변수를 메모리 내 블록에 저장하고, 블록의 주소를 레지스터에 매개변수로 넣어 전달한다. ( Linux와 Solaris가 사용하는 방법 )
  3. 스택 이용 : 프로그램에 의해 매개변수가 스택에 넣어지고(push), 운영체제에 의해 꺼내어진다(pop off).
tip

운영체제는 블록이나 스택 방법을 선호하는데 , 이는 전달되는 매개변수 개수나 용량이 제한 받지 않기 때문이다.

syscall_memory

위 그림은 2의 과정인 메모리 블록을 이용한 방법을 나타낸 그림이다.

예상되는 면접 질문

  • 사용자가 시스템 콜을 호출했을 때 일어나는 과정에 대해 설명해주세요
  • 시스템 콜이란 무엇이며, 왜 사용하나요?
  • 시스템 콜의 매개변수 전달 방법중 레지스터를 이용하는 방법이 있습니다. 이 방법의 단점이 있을까요?

참고자료

기여자


HongEunho

📦